#include <hpdf.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <ft2build.h>
#include <freetype/freetype.h>

#define X_INTEVAL 30
#define Y_INTEVAL 30

#define START_X 100
#define START_Y 100

#define FONT_FAIL_PATH "simsun.ttf"

std::string unicodeToUtf8(unsigned int code_point) {
    std::string utf8_string;

    if (code_point <= 0x7F) {
        utf8_string += static_cast<char>(code_point & 0x7F);
    } else if (code_point <= 0x7FF) {
        utf8_string += static_cast<char>(0xC0 | ((code_point >> 6) & 0x1F));
        utf8_string += static_cast<char>(0x80 | (code_point & 0x3F));
    } else if (code_point <= 0xFFFF) {
        utf8_string += static_cast<char>(0xE0 | ((code_point >> 12) & 0x0F));
        utf8_string += static_cast<char>(0x80 | ((code_point >> 6) & 0x3F));
        utf8_string += static_cast<char>(0x80 | (code_point & 0x3F));
    } else if (code_point <= 0x10FFFF) {
        utf8_string += static_cast<char>(0xF0 | ((code_point >> 18) & 0x07));
        utf8_string += static_cast<char>(0x80 | ((code_point >> 12) & 0x3F));
        utf8_string += static_cast<char>(0x80 | ((code_point >> 6) & 0x3F));
        utf8_string += static_cast<char>(0x80 | (code_point & 0x3F));
    }
    return utf8_string;
}


int main()
{
    // 初始化FreeType库
    FT_Library ft_library;
    if (FT_Init_FreeType(&ft_library)) {
        fprintf(stderr, "无法初始化FreeType库\n");
        return 1;
    }

    // 创建一个新的PDF文档对象
    HPDF_Doc pdf = HPDF_New(NULL, NULL);
    if (!pdf)
    {
        fprintf(stderr, "不能创建pdf对象\n");;
        return 1;
    }

    // 使用 UTF-8 编码
    HPDF_UseUTFEncodings(pdf);
    HPDF_SetCurrentEncoder(pdf, "UTF-8");

    // 添加一个新页面到文档
    HPDF_Page page = HPDF_AddPage(pdf);

    // 设置页面大小（A4：宽210mm，高297mm）
    HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);

    //加载字体
    const char* fontname = HPDF_LoadTTFontFromFile(pdf, FONT_FAIL_PATH, HPDF_TRUE);
    if (!fontname) {
        fprintf(stderr, "无法加载字体文件\n");
        return 1;
    }

    // 获取字体并设置页面字体和大小
    HPDF_Font font = HPDF_GetFont(pdf, fontname, "UTF-8");
    HPDF_Page_SetFontAndSize(page, font, 12);

    // 加载字体（使用FreeType）
    FT_Face ft_face;
    if (FT_New_Face(ft_library, FONT_FAIL_PATH, 0, &ft_face)) {
        fprintf(stderr, "无法加载字体文件\n");
        FT_Done_FreeType(ft_library);
        return 1;
    }
    // 设置字体大小（FreeType）
    if (FT_Set_Pixel_Sizes(ft_face, 0, 12 * 64)) { // 12 points, converted to 1/64th of a point
        fprintf(stderr, "无法设置字体大小\n");
        FT_Done_Face(ft_face);
        FT_Done_FreeType(ft_library);
        return 1;
    }

    /*这行代码一定要放到移动文本位置之前*/
    HPDF_Page_BeginText(page);
    
    // 开始在页面上添加文本
    float width = HPDF_Page_GetWidth(page);
    float height = HPDF_Page_GetHeight(page);
    float x = START_X, y = height - START_Y;
    HPDF_Page_MoveTextPos(page, x, y);

    int line = 0, count = 0;
     auto fontdef = HPDF_GetTTFontDefFromFile(pdf, FONT_FAIL_PATH, 1);
     FT_ULong char_code;
    FT_Bool has_glyph;
    for(unsigned int char_code = 0x0000; char_code < 0xFFFF; char_code++)
    {
        // if (HPDF_TTFontDef_GetGlyphid(fontdef, char_code) == 0)
        //     continue;
        has_glyph = FT_Get_Char_Index(ft_face, char_code) != 0;
        if (!has_glyph)  continue;
            
		std::string utf8_string = unicodeToUtf8(char_code);
        HPDF_Page_ShowText(page, utf8_string.c_str());
        HPDF_Page_MoveTextPos(page, X_INTEVAL, 0);
        count++;
        if(count % 10 == 0)
        {
            // 换行
            HPDF_Page_MoveTextPos(page, -10 * X_INTEVAL, -Y_INTEVAL);
            line++;
        }

        if(line == 20)
        {
            HPDF_Page_EndText(page);
            page = HPDF_AddPage(pdf);
            HPDF_Page_BeginText(page);
            HPDF_Page_SetFontAndSize(page, font, 12);
            HPDF_Page_MoveTextPos(page, x, y);
            line = 0;
            count = 0;
        }
        
    }
    
    // 将文档保存到文件
    HPDF_STATUS status;

    const char *filename = "test.pdf";
    status = HPDF_SaveToFile(pdf, filename);
    if (status != HPDF_OK) {
        fprintf(stderr, "文件保存失败\n");
        HPDF_Free(pdf);
        return 1;
    }

    // 释放文档对象所占用的资源
    HPDF_Free(pdf);

    // 释放FreeType资源
    FT_Done_Face(ft_face);
    FT_Done_FreeType(ft_library);

    return 0;
}